#ifndef RCTCPSOCKET_H
#define RCTCPSOCKET_H

#include <QtCore/QByteArray>
#include <QtCore/QSet>
#include <QtCore/QTime>
#include <QtNetwork/QTcpSocket>

class RcTcpSocket : public QTcpSocket
{
    Q_OBJECT
public:
    RcTcpSocket(QObject *parent = 0);

    inline bool canReadLine() const { return incoming.contains('\n'); }

    qint64 writeToSocket(qint64 maxlen);
    qint64 readFromSocket(qint64 maxlen);

    inline bool canTransferMore() const;
    qint64 bytesAvailable() const;
    inline qint64 socketBytesAvailable() const { return QTcpSocket::bytesAvailable(); }

signals:
    void readyToTransfer();

protected:
    qint64 readData(char *data, qint64 maxlen);
    qint64 readLineData(char *data, qint64 maxlen);
    qint64 writeData(const char *data, qint64 len);

private:
    QByteArray outgoing;
    QByteArray incoming;
};

class RateController : public QObject
{
    Q_OBJECT
public:
    inline RateController(QObject *parent = 0)
	: QObject(parent), transferScheduled(false) { }

    void addSocket(RcTcpSocket *socket);
    void removeSocket(RcTcpSocket *socket);

    inline int uploadLimit() const { return upLimit; }
    inline int downloadLimit() const { return downLimit; }
    inline void setUploadLimit(int bytesPerSecond) { upLimit = bytesPerSecond; }
    void setDownloadLimit(int bytesPerSecond);

public slots:
    void transfer();
    void scheduleTransfer();

private:
    QTime stopWatch;
    QSet<RcTcpSocket *> sockets;
    int upLimit;
    int downLimit;
    bool transferScheduled;
};

#endif
